using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class PlayerToolAnimationFrame {
	public float duration;
	public Vector3 translation;
	public Quaternion rotation;
	
	public PlayerToolAnimationFrame(
		float duration,
		Vector3 translation,
		Quaternion rotation) {
		this.duration = duration;
		this.translation = translation;
		this.rotation = rotation;
	}
}

public class PlayerToolAnimation {
	/** 
	 * binary tree makes more sense for finding the time interval
	 * however, it's kind of overkill since we'll only have a few frames
	 */
	List<PlayerToolAnimationFrame> frames;
	int frame_index;
	bool begun;
	bool first_frame_returned;
	/* Ended means we're done, but waiting on caller to EndAnimation() */
	bool ended;
	float elapsed_time;
	
	const bool DEBUG = true;
	
	public PlayerToolAnimation() {
		this.frame_index = -1;
		this.begun = false;
		this.ended = false;
		this.elapsed_time = 0;
		this.frames = new List<PlayerToolAnimationFrame>();
	}
	
	public void BeginAnimation() {
		this.elapsed_time = 0;
		this.begun = true;
		this.first_frame_returned = false;
		this.ended = false;
		this.frame_index = 0;
	}
	
	public bool HasAnimationBegun() {
		return this.begun;
	}
	
	public void EndAnimation() {
		this.begun = false;
		this.frame_index = -1;
	}
	
	public PlayerToolAnimationFrame CheckNextFrame(float time_delta, out bool ended) {
		PlayerToolAnimationFrame f;
		
		ended = true;
		
		if (!this.HasAnimationBegun()) {
			return null;
		}
		
		if (this.ended) {
			return null;
		}
		
		f = this.GetCurrentFrame ();
		if (f == null) {
			return null;
		}
		
		if (!this.first_frame_returned) {
			/* first frame does not need a duration check */
			ended = false;
			this.first_frame_returned = true;
			return f;
		}
		
		this.elapsed_time += time_delta;
		if (this.elapsed_time < f.duration) {
			/* Don't advance frame yet; not enough time elapsed */
			ended = false;
			return null;
		}
		
		this.elapsed_time = 0;
		if (!this.AdvanceFrame ()) {
			/* Animation's done */
			this.ended = true;
			ended = true;
			return null;
		} else {
			ended = false;
			return this.GetCurrentFrame();
		}
	}
	
	/* return true when wrapped around */
	bool AdvanceFrame() {
		this.frame_index++;
		if (this.frame_index >= this.frames.Count) {
			this.frame_index = -1;
			return false;
		} else {
			return true;
		}
	}
	
	public bool IsFirstFrame() {
		return (this.frame_index == 0);
	}
	
	public PlayerToolAnimationFrame GetCurrentFrame() {
		if (this.frame_index < 0) {
			return null;
		}
		
		return this.frames[this.frame_index];
	}
	
	public void AddFrame(PlayerToolAnimationFrame frame) {
		this.frames.Add(frame);
	}
}